package top.honlnk.czuan.common.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.honlnk.czuan.common.constant.DictOptionConstant;
import top.honlnk.czuan.common.exception.CustomException;
import top.honlnk.czuan.mapper.dict.BaiduDictMapper;
import top.honlnk.czuan.pojo.dto.dict.BaiduDictDTO;
import top.honlnk.czuan.pojo.entity.BaiduServeInfo;

import java.util.*;

@Slf4j
@Component
public class BaiduDictUtil {

    @Autowired
    private BaiduDictMapper baiduDictMapper;
    @Autowired
    private GetBaiduAccessTokenUtil getBaiduAccessTokenUtil;

    // 将百度词典服务信息baiduServeInfo与用户参数，全局化
    private BaiduServeInfo baiduServeInfo;
    private BaiduDictDTO baiduDictDTO;

    // 设置access_token
    private String setAccessToken(@NotNull BaiduServeInfo baiduServeInfo) {
        String accessToken = getBaiduAccessTokenUtil.getAccessToken(baiduServeInfo.getApiKey(), baiduServeInfo.getSecretKey());
        baiduDictMapper.setAccessToken(accessToken, DictOptionConstant.BAIDU_TEXT_DICT);
        return accessToken;
    }

    // 百度文本翻译，词典版
    public JSONObject baiduDict(BaiduDictDTO baiduDictDTO) {
        this.baiduDictDTO = baiduDictDTO;
        BaiduServeInfo baiduServeInfo = baiduDictMapper.getBaiduServeInfo(DictOptionConstant.BAIDU_TEXT_DICT);
        if (baiduServeInfo == null) {
            throw new CustomException("百度词典服务未配置");
        }
        String accessToken = baiduServeInfo.getAccessToken();
        if (accessToken == null) {accessToken = setAccessToken(baiduServeInfo);}
        this.baiduServeInfo = baiduServeInfo;

        String apiUrl = baiduServeInfo.getApiUrl();
        String url = apiUrl + "?access_token=" + accessToken;

        String result = HttpRequest.post(url)
                .header("Content-Type", "application/json;charset=utf-8")
                .body(JSONUtil.toJsonStr(baiduDictDTO))
                .timeout(10000)
                .execute().body();

        JSONObject resultJSONObj = JSONUtil.parseObj(result);
        // 判断是否有异常
        resultJSONObj = errorHandle(resultJSONObj);

        // 解析请求结果中来自dict的数据
        JSONObject endResult = analysisDict(resultJSONObj);
        log.info("百度翻译结果解析完毕，最终结果: {}", endResult);
        return endResult;

    }
    // 百度文本翻译词典版，异常处理
    private JSONObject errorHandle(@NotNull JSONObject jsonObject) {
        // 判断是否有异常
        if (jsonObject.getInt("error_code") != null) {
            log.error("百度词典出现异常，错误码：{}，错误信息：{}", jsonObject.getInt("error_code"), jsonObject.getStr("error_msg"));
            switch (jsonObject.getInt("error_code")) {
                case 1:
                    throw new CustomException("百度词典：服务异常");
                case 2:
                    throw new CustomException("百度词典：服务处理超时");
                case 4:
                    throw new CustomException("百度词典：集群超限额");
                case 6:
                    throw new CustomException("百度词典：无权限请求");
                case 18:
                case 31104:
                    throw new CustomException("百度词典：请求频率过高");
                case 19:
                case 31005:
                    throw new CustomException("百度词典：额度用尽");
                case 100:
                    throw new CustomException("百度词典：请求参数不合法");
                case 110:
                case 111:
                    String accessToken = setAccessToken(this.baiduServeInfo);
                    log.warn("token失效/过期，以重新获取access_token：{}", accessToken);
                    return baiduDict(this.baiduDictDTO);
                case 20003:
                    throw new CustomException("百度词典：请求内容存在风险");
                case 31101:
                    throw new CustomException("百度词典：请求超时，请重试");
                case 31105:
                    String to = this.baiduDictDTO.getTo();
                    throw new CustomException("百度词典：不支持翻译的目标语言：" + to);
                case 31106:
                case 31201:
                    throw new CustomException("百度词典：请求翻译的原文太长（最长不得超过6000字节）");
                case 31006:
                case 282000:
                    throw new CustomException("百度词典：内部服务出现异常");
                default:
                    throw new CustomException("百度词典：未知异常");
            }
        } else if (jsonObject.getInt("log_id") != null){
            return jsonObject;
        } else {
            log.error("百度词典出现未知异常，请求结果：{}", jsonObject);
            throw new CustomException("百度词典未知异常");
        }
    }
    // 百度文本翻译词典版，解析请求结果“dict”
    @Contract("_ -> param1")
    private @NotNull JSONObject analysisDict(@NotNull JSONObject jsonObject) {
        // 获取 result 对象
        JSONObject resultObj = jsonObject.getJSONObject("result");
        if (resultObj == null) {
            log.warn("在响应中找不到“result”。");
            throw new CustomException("百度词典：响应结果异常");
        }

        // 获取 trans_result 数组
        JSONArray transResultArray = resultObj.getJSONArray("trans_result");
        if (transResultArray == null) {
            log.warn("在响应中找不到“trans_result”。");
            throw new CustomException("百度词典：响应结果异常");
        }

        if (transResultArray.isEmpty()) {
            log.info("百度词典：没有找到翻译结果");
            return jsonObject;
        } else {
            for (int i = 0; i < transResultArray.size(); i++) {
                JSONObject transResult = transResultArray.getJSONObject(i);
                String dictJsonStr = transResult.getStr("dict");
                if (dictJsonStr == null) {
                    log.warn("在请求结果的第 {} 个值中没有找到“dict”", i + 1);
                } else if (dictJsonStr.isEmpty()) {
                    log.warn("在请求结果的第 {} 个值中“dict”的值为空字符串", i + 1);
                } else {
                    JSONObject dictObj = JSONUtil.parseObj(dictJsonStr);
                    transResult.set("dict", dictObj);
                    transResultArray.set(i, transResult);
                }
            }
            resultObj.set("trans_result", transResultArray);
        }
        jsonObject.set("result", resultObj);

        return jsonObject;
    }

    public JSONObject getDictInfo(@NotNull JSONObject transResult) {
        return transResult.containsKey("dict") ? transResult.getJSONObject("dict") : new JSONObject();
    }

    public JSONObject getTtsFile(@NotNull JSONObject transResult) {

        JSONObject ttsObjs = JSONUtil.createObj();

        // 获取 请求结果中的“获取发音地址”的URL地址
        String dstTtsStrServeUrl = transResult.getStr("dst_tts");
        if (!dstTtsStrServeUrl.isEmpty()) {
            byte[] dstTtsByte = HttpUtil.createGet(dstTtsStrServeUrl).execute().bodyBytes();
            String dstTtsBase64 = Base64.getEncoder().encodeToString(dstTtsByte);
            ttsObjs.set("dstTtsFileBase64", dstTtsBase64); // 汉语发音
        } else {
            ttsObjs.set("dstTtsFileBase64", "");
        }

        String srcTtsStrServeUrl = transResult.getStr("src_tts");
        if (!srcTtsStrServeUrl.isEmpty()) {
            byte[] srcTtsByte = HttpUtil.createGet(srcTtsStrServeUrl).execute().bodyBytes();
            String srcTtsBase64 = Base64.getEncoder().encodeToString(srcTtsByte);
            ttsObjs.set("srcTtsFileBase64", srcTtsBase64); // 英语发音
        } else {
            ttsObjs.set("srcTtsFileBase64", "");
        }
        return  ttsObjs;
    }

    public String getSrc(@NotNull JSONObject edict) {
        return edict.containsKey("src") ? edict.getStr("src") : "";
    }

    public String getDst(@NotNull JSONObject common) {
        return common.containsKey("text") ? common.getStr("text") : "";
    }

    public Map<String, String> getSymbols(@NotNull JSONObject symbol) {
        String en = symbol.getStr("ph_en");
        String us = symbol.getStr("ph_am");

        Map<String, String> resultSymbols = new HashMap<>();
        resultSymbols.put("en", en == null ? "" : en );
        resultSymbols.put("us", us == null ? "" : us );

        // 判断symbolsList的长度是否超过1，若超过1key的命名为：单词本身，否则key的命名为：单词本身 + 索引
        return resultSymbols;
    }

    public Map<String, List<String>> getTranslation(@NotNull JSONObject symbol) {
        Map<String, List<String>> partSpeechSymbols = new HashMap<>();
        if (symbol.containsKey("parts")) {
            JSONArray parts = symbol.getJSONArray("parts");
            for (int j = 0; j < parts.size(); j++) {
                JSONObject part = parts.getJSONObject(j);
                JSONArray translationJSONArray = part.getJSONArray("means");
                List<String> translationList = JSONUtil.toList(translationJSONArray, String.class);
                String partKey = part.getStr("part");
                if (partKey.isEmpty()) {
                    partKey = "null.";
                }
                partSpeechSymbols.put(partKey, translationList);
            }
        }


        // 判断symbolsList的长度是否超过1，若超过1key的命名为：单词本身，否则key的命名为：单词本身 + 索引
        return partSpeechSymbols;
    }

    public Map<String, List<String>> getExchange(@NotNull JSONObject exchange) {
        Map<String, List<String> > resultSymbols = new HashMap<>();
        for (String key : exchange.keySet()) {
            resultSymbols.put(key, exchange.getJSONArray(key).toList(String.class));
        }

        return resultSymbols;
    }

    private @NotNull String setWordKey(@NotNull JSONArray transResultArray, Integer i) {
            return transResultArray.getJSONObject(i).getStr("src") + "-" + (i + 1);
    }
}























